package core.manager.battle
{
	import as3isolib.geom.Pt;
	
	import flash.geom.Point;
	
	import isoengine.interfaces.IIsoWorld;
	import isoengine.pathing.Node;
	import isoengine.world.IsoMapSprite;
	
	import mapengine.avatars.AvatarBase;
	import mapengine.avatars.IGameAvatar;
	
	import values.skill.AIType;
	import values.skill.SkillValue;

	public class BattleAIManager
	{
		/**
		 * 找到技能的行动顺序 
		 * @param avatar
		 * @param skillV
		 * @return 
		 * 
		 */		
		public static function checkSkillStep(avatar:IGameAvatar , skillV:SkillValue):Array
		{
			var world:IIsoWorld = avatar.world;
			var skillList:Array;
			if(skillV.template.target == 3 )
			{
				if(skillV.template.rangeTarget == 3 || skillV.template.rangeTarget == 1)
				{
					return [{owner:avatar , target:avatar , command:skillV.isUltimateSkill ? "use_ultimate" : "use_skill" }];
				}
				else
				{
					var list:Vector.<IsoMapSprite> = world.rangeOnType(skillV.range.key , new Point(avatar.avatarValue.x , avatar.avatarValue.y) , false , false);
					var haveTarget:Boolean = false;
					for each(var v:IGameAvatar in list)
					{
						if(skillV.template.rangeTarget == -1)
						{
							if(v.avatarValue.party * avatar.avatarValue.party < 0) 
							{
								haveTarget = true;
								break;
							}
						}
						else
						{
							if(skillV.template.rangeTarget == 4)
							{
								if(v != avatar && v.avatarValue.party * avatar.avatarValue.party > 0)
								{
									haveTarget = true;
									break;
								}
							}
						}
					}
					
					if(haveTarget)
					{
						return [{owner:avatar , target:avatar , command:skillV.isUltimateSkill ? "use_ultimate" : "use_skill" }];
					}
					else
					{
						return null;
					}
				}
			}
			
			skillList = findAllTarget(avatar , 
				skillV.template.target == -1 ? 
					( avatar.avatarValue.party == -1 ? BattleManager.battleManager.getAvatarsBySide(0)  : BattleManager.battleManager.getAvatarsBySide(1)) 
						: ( avatar.avatarValue.party == -1 ? BattleManager.battleManager.getAvatarsBySide(1) : BattleManager.battleManager.getAvatarsBySide(0)) , 
							skillV.distance + avatar.avatarValue.moveCapability , 
								skillV.template.target == 4 ? false : true);
			
			var target:IGameAvatar = findAITarget(skillV.template.ai , skillList , avatar);
			var distance:int = avatar.distanceToSprite(target , false);
			if(distance <= skillV.distance)
			{
				return [{owner:avatar , target:target , command:skillV.isUltimateSkill ? "use_ultimate" : "use_skill"}];
			}
			
			if(distance <= skillV.distance + avatar.avatarValue.moveCapability)
			{
				var returnArr:Array = [];
				var nodeArr:Array = world.pathA2B(new Point(avatar.avatarValue.x , avatar.avatarValue.y) ,
					new Point(target.avatarValue.x , target.avatarValue.y));
				
				var targetNode:Node = nodeArr[nodeArr.length - skillV.distance - 1];
				returnArr.push({owner:avatar , target:targetNode , command:"move"});
				returnArr.push({owner:avatar , target:target , command:skillV.isUltimateSkill ? "use_ultimate" : "use_skill"});
				return returnArr;
			}
			
			return null;
		}
		
		private static function findAITarget(ai:int , list:Array , avatar:IGameAvatar):IGameAvatar
		{
			switch(ai)
			{
				case AIType.RANDOM_ONE:
					return findRandomTarget(list);
					break;
				case AIType.CLOSE_ONE:
					return findNearestTarget(avatar , list);
					break;
				case AIType.HP_MIN_ONE:
					return findHPMinTarget(list);
					break;
				default:
					throw new Error("角色攻击AI配置错误!!!!");
					break;
			}
			
			return null;
		}
		
		/**
		 *  普通攻击的AI
		 * @param avatar
		 * @return 
		 * 
		 */		
		public static function checkNormalStep(avatar:IGameAvatar):Array
		{
			var attackList:Array = findAllTarget(
				avatar , 
				avatar.avatarValue.party == -1 ? BattleManager.battleManager.getAvatarsBySide(1) : BattleManager.battleManager.getAvatarsBySide(0) , 
				avatar.avatarValue.distance + avatar.avatarValue.moveCapability);
			var target:IGameAvatar = findAITarget(avatar.avatarValue.template.ai , attackList , avatar);
			if(!target)
			{
				target = findNearestTarget(avatar , 
				avatar.avatarValue.party == -1 ? BattleManager.battleManager.getAvatarsBySide(1) : BattleManager.battleManager.getAvatarsBySide(0));
			}
			
			var world:IIsoWorld = avatar.world;
			var distance:int = avatar.distanceToSprite(target , false);
			var returnArr:Array = [];
			if(distance <= avatar.avatarValue.distance)
			{
				return [{owner:avatar , target:target , command:"attack"}];
			}
			
			var nodeArr:Array = world.pathA2B(new Point(avatar.avatarValue.x , avatar.avatarValue.y) ,
				new Point(target.avatarValue.x , target.avatarValue.y));
			
			if(distance <= avatar.avatarValue.distance + avatar.avatarValue.moveCapability)
			{
				var targetNode:Node = nodeArr[nodeArr.length - avatar.avatarValue.distance - 1];
				returnArr.push({owner:avatar , target:targetNode , command:"move"});
				returnArr.push({owner:avatar , target:target , command:"attack"});
				
				return returnArr;
			}
			
			return [{owner:avatar , target:nodeArr[avatar.avatarValue.moveCapability] , command:"move"} , 
				{owner:avatar , target:null ,  command:"standby"}];
		}
		
		/**
		 * 找到最近的目标 
		 * @param avatar
		 * @param arr
		 * @return 
		 * 
		 */		
		private static function findNearestTarget(avatar:IGameAvatar , arr:Array):IGameAvatar
		{
			var world:IIsoWorld = avatar.world;
			var short:Object = {distance:int.MAX_VALUE , avatarV:null};
			
			for each(var ar:IGameAvatar in arr)
			{
				var distance:Number = ar.distanceToSprite(avatar , false);
				if(distance < short.distance)
				{
					short = {distance:distance , avatarV:ar};
				}
			}
			
			return short.avatarV;
		}
		
		
		/**
		 * 寻找血最少的目标 
		 * @param arr
		 * @return 
		 * 
		 */		
		private static function findHPMinTarget(arr:Array):IGameAvatar
		{
			var currentTarget:IGameAvatar = null;
			for each(var t:IGameAvatar in arr)
			{
				if(!currentTarget) currentTarget = t;
				else
				{
					if(currentTarget.avatarValue.hp / currentTarget.avatarValue.maxHP > t.avatarValue.hp / t.avatarValue.maxHP)
					{
						currentTarget = t;
					}
				}
			}
			
			return currentTarget;
		}
		
		/**
		 * 寻找随机目标 
		 * @param avatar
		 * @param arr
		 * @param distance
		 * @return 
		 * 
		 */		
		private static function findRandomTarget(arr:Array):IGameAvatar
		{
			if(!arr || arr.length == 0) return null;
			return arr[Math.floor(Math.random() * arr.length)];
		}
		
		/**
		 * 找到范围内所有目标 
		 * @param avatar
		 * @param arr
		 * @param distance
		 * @return 
		 * 
		 */		
		private static function findAllTarget(avatar:IGameAvatar , arr:Array , distance:int , includeMe:Boolean = false):Array
		{
			var world:IIsoWorld = avatar.world;
			var arrReturn:Array = [];
			
			for each(var ar:IGameAvatar in arr)
			{
				if(distance >= ar.distanceToSprite(avatar , false) && ( (!includeMe && avatar != ar) || includeMe ))
				{
					arrReturn.push(ar);
				}
			}
			
			return arrReturn;
		}
	}
}